home *** CD-ROM | disk | FTP | other *** search
- /*
-
- Window procedure for connection MDI window
-
- */
-
- #include "netfone.h"
-
- #define ASYNC_OUTPUT
-
- static struct {
- char header[4];
- unsigned short len, ilen;
- soundbuf sbm;
- } mb = {{1, 2, 3, 4}};
- #define sb mb.sbm
-
- soundbuf ebuf; // Utility sound buffer
- static struct adpcm_state adpcm; // ADPCM compression state
-
- extern long outputPending;
- char blankit[] = " "
- " "
- " ";
-
- /* GSMCOMP -- Compress the contents of a sound buffer using GSM. */
-
- static void gsmcomp(soundbuf *asb)
- {
- gsm_signal src[160];
- gsm_frame dst;
- int i, j, l = 0;
- char *dp = (asb->buffer.buffer_val) + sizeof(short);
- long ldata = asb->buffer.buffer_len;
-
- for (i = 0; i < ldata; i += 160) {
- for (j = 0; j < 160; j++) {
- if ((i + j) < asb->buffer.buffer_len) {
- src[j] = audio_u2s(asb->buffer.buffer_val[i + j]);
- } else {
- src[j] = 0;
- }
- }
- gsm_encode(gsmh, src, dst);
- _fmemcpy(dp, dst, sizeof dst);
- dp += sizeof dst;
- l += sizeof dst;
- }
-
- /* Hide original uncompressed buffer length in first 2 bytes of buffer. */
-
- *((short *) asb->buffer.buffer_val) = (short) ldata;
- revshort((short *) asb->buffer.buffer_val);
- asb->buffer.buffer_len = l + sizeof(short);
- }
-
- /* ADPCMCOMP -- Compress the contents of a sound buffer using ADPCM. */
-
- static void adpcmcomp(soundbuf *asb)
- {
- unsigned char *dp = (unsigned char *) asb->buffer.buffer_val;
- struct adpcm_state istate;
-
- istate = adpcm;
- adpcm_coder_u(dp, (char *) dp, (int) asb->buffer.buffer_len, &adpcm);
- asb->buffer.buffer_len /= 2;
-
- /* Hide the ADPCM encoder state at the end of this buffer.
- The shifting and anding makes the code byte-order
- insensitive. */
-
- dp += asb->buffer.buffer_len;
- *dp++ = ((unsigned int) istate.valprev) >> 8;
- *dp++ = istate.valprev & 0xFF;
- *dp = istate.index;
- asb->buffer.buffer_len += 3;
- }
-
- /* LPCCOMP -- Compress the contents of a sound buffer using LPC. */
-
- static void lpccomp(asb)
- struct soundbuf *asb;
- {
- int i, l = 0;
- char *dp = ((char *) asb->buffer.buffer_val) + sizeof(short);
- unsigned char *src = ((unsigned char *) asb->buffer.buffer_val);
- lpcparams_t lp;
-
- asb->compression |= fCompLPC;
- for (i = 0; i < asb->buffer.buffer_len; i += 180) {
- lpc_analyze(src + i, &lp);
- revshort(&(lp.period));
- _fmemcpy(dp, &lp, sizeof lp);
- dp += sizeof lp;
- l += sizeof lp;
- }
-
- // Hide original uncompressed buffer length in first 2 bytes of buffer.
-
- *((short *) asb->buffer.buffer_val) = (short) asb->buffer.buffer_len;
- revshort((short *) asb->buffer.buffer_val);
- asb->buffer.buffer_len = l + sizeof(short);
- }
-
- /* COMPRESS2X -- Compress a sound buffer with Simple (discard every
- other sample) compression. If you're doing both
- Simple and GSM compression, Simple compression must be
- done first. */
-
- void compress2X(soundbuf *asb)
- {
- LONG i;
-
- asb->buffer.buffer_len /= 2;
- for (i = 1; i < asb->buffer.buffer_len; i++) {
- asb->buffer.buffer_val[i] = asb->buffer.buffer_val[i * 2];
- }
- }
-
- // WRITEOUTPUT -- Transmit output buffer to destination
-
- static int writeOutput(LPCLIENT_DATA d, LPSTR buf, int buflen)
- {
- if (d->modemConnection) {
- if (modemHandle != -1) {
- unsigned short bcrc;
- COMSTAT cs;
- int wrl, err;
-
- mb.len = (unsigned short) buflen;
- mb.ilen = ~mb.len;
- revshort(&mb.len);
- revshort(&mb.ilen);
- bcrc = crc((LPSTR) &mb, buflen + 4 + 2 * sizeof(unsigned short));
- revshort(&bcrc);
- err = GetCommError(modemHandle, &cs);
- if (err != 0) {
- MsgBox(hwndMDIFrame, MB_ICONSTOP | MB_OK, Format(20), err);
- errorRant(hwndMDIFrame);
- return -1;
- }
- wrl = WriteComm(modemHandle, &mb, buflen + 4 + 2 * sizeof(unsigned short));
- err = GetCommError(modemHandle, &cs);
- if (err != 0) {
- MsgBox(hwndMDIFrame, MB_ICONSTOP | MB_OK, Format(21), err);
- errorRant(hwndMDIFrame);
- return -1;
- }
- if (wrl > 0) {
- wrl = WriteComm(modemHandle, &bcrc, sizeof(short));
- }
- err = GetCommError(modemHandle, &cs);
- if (err != 0) {
- MsgBox(hwndMDIFrame, MB_ICONSTOP | MB_OK, Format(22), err);
- errorRant(hwndMDIFrame);
- return -1;
- }
- return buflen;
- }
- } else {
- int stat;
-
- if ((!useSendNotSendto || waNetNoConnect) && (!waNetUseSend)) {
- //if (packetsSent == 200) { stat = -1; } else
- stat = sendto(d->sReply, buf, buflen, 0,
- (LPSOCKADDR) &(d->name), sizeof d->name);
- if (stat < 0) {
- if (!waNetNoConnect) {
- useSendNotSendto = TRUE;
- if (hDlgPropeller != NULL) {
- SetDlgItemText(hDlgPropeller, IDC_PH_SENDTO, rstring(IDS_T_SEND));
- }
- }
- }
- }
- /* Careful! Don't "optimise" this to "else if"; we have to be
- able to switch-hit when the first sendto() fails above. */
- if (useSendNotSendto) {
- stat = send(d->sReply, buf, buflen, 0);
- }
- if (stat >= 0) {
- d->outputSocketBusy = TRUE;
- propeller(IDC_PH_PACKETS_SENT, ++packetsSent);
- } else {
- propeller(IDC_PH_OUTPUT_LOST, ++outputPacketsLost);
- }
- return stat;
- }
- }
-
- // SOCKETERRORBOX -- Show message box for socket error
-
- static void socketerrorbox(HWND hwnd, LPCLIENT_DATA d)
- {
- if (d->modemConnection) {
- MessageBox(hwnd, rstring(IDS_T_MODEM_WRITE_ERR), NULL,
- MB_ICONEXCLAMATION | MB_OK);
- } else {
- MessageBox(hwnd, SockerrToString(WSAGetLastError()), rstring(IDS_T_SOCKET_WRITE_ERR),
- MB_ICONEXCLAMATION | MB_OK);
- }
- }
-
- /* SENDPKT -- Send a message to the destination. */
-
- static int sendpkt(HWND hwnd, LPCLIENT_DATA d, struct soundbuf *asb)
- {
- LONG lts = asb->buffer.buffer_len;
-
- if (d->deskey[0] || d->ideakey[0] || d->opgpkey[0] || d->otpFileName[0]) {
- int i;
- LONG slen;
-
- _fmemcpy(&ebuf, asb, (int) ((sizeof(struct soundbuf) - BUFL) + lts));
- slen = lts;
-
- /* DES encryption. */
-
- if (d->deskey[0]) {
- char twibble[8];
-
- _fmemcpy(twibble, d->deskey + 1, 8);
- setkey(twibble);
-
- /* If we're DES encrypting we must round the size of
- the data to be sent to be a multiple of 8 so that
- the entire DES frame is sent. */
-
- slen = (slen + 7) & (~7);
- for (i = 0; i < slen; i += 8) {
-
- /* Apply cipher block chaining within the packet. */
-
- if (i > 0) {
- int j;
-
- for (j = 0; j < 8; j++) {
- ebuf.buffer.buffer_val[(i + j)] ^=
- ebuf.buffer.buffer_val[(i + j) - 8];
- }
- }
- endes(ebuf.buffer.buffer_val + i);
- }
- ebuf.compression |= fEncDES;
- }
-
- /* IDEA encryption. */
-
- if (d->ideakey[0]) {
- unsigned short iv[4];
- char twibble[16];
-
- _fmemcpy(twibble, d->ideakey + 1, 16);
- memset(iv, 0, sizeof(iv));
- initcfb_idea(iv, twibble, FALSE);
-
- /* If we're IDEA encrypting we must round the size of
- the data to be sent to be a multiple of 8 so that
- the entire IDEA frame is sent. */
-
- slen = (slen + 7) & (~7);
- ideacfb(ebuf.buffer.buffer_val, (int) slen);
- close_idea();
- ebuf.compression |= fEncIDEA;
- }
-
- /* PGP session key encryption. */
-
- if (d->opgpkey[0]) {
- unsigned short iv[4];
- char twibble[16];
-
- _fmemcpy(twibble, d->opgpkey + 1, 16);
- memset(iv, 0, sizeof(iv));
- initcfb_idea(iv, twibble, FALSE);
-
- /* If we're IDEA encrypting we must round the size of
- the data to be sent to be a multiple of 8 so that
- the entire IDEA frame is sent. */
-
- slen = (slen + 7) & (~7);
- ideacfb(ebuf.buffer.buffer_val, (int) slen);
- close_idea();
- ebuf.compression |= fEncPGP;
- }
-
- /* One-time pad encryption. */
-
- if (d->otpFileName[0]) {
- for (i = 0; i < slen; i++) {
- ebuf.buffer.buffer_val[i] ^= d->otp[i];
- }
- ebuf.compression |= fEncOTP;
- }
- revlong(&ebuf.compression);
- revlong(&ebuf.buffer.buffer_len);
-
- if (writeOutput(d, (LPSTR) &ebuf,
- (int) ((sizeof(struct soundbuf) - BUFL) + slen)) < 0) {
- d->state = d->wantsInput ? SendingLiveAudio : Idle;
- if (d->hFile != HFILE_ERROR) {
- KillTimer(hwnd, 2);
- _lclose(d->hFile);
- d->hFile = HFILE_ERROR;
- }
- socketerrorbox(hwnd, d);
- return FALSE;
- }
- } else {
- int stat;
-
- revlong(&asb->compression);
- revlong(&asb->buffer.buffer_len);
- stat = writeOutput(d, (LPSTR) asb,
- (int) ((sizeof(struct soundbuf) - BUFL) + lts));
- revlong(&asb->compression);
- revlong(&asb->buffer.buffer_len);
- if (stat < 0) {
- d->state = d->wantsInput ? SendingLiveAudio : Idle;
- d->wantsInput = FALSE;
- if (d->hFile != HFILE_ERROR) {
- KillTimer(hwnd, 2);
- _lclose(d->hFile);
- d->hFile = HFILE_ERROR;
- }
- socketerrorbox(hwnd, d);
- return FALSE;
- }
- }
- return TRUE;
- }
-
- /* SHIPSOUNDBUFFER -- Output sound buffer to connection. */
-
- void shipSoundBuffer(HWND hwnd, LPCLIENT_DATA pClientData)
- {
- sb.compression = pClientData->ring ? (fSetDest | fDestSpkr) : 0;
- pClientData->ring = FALSE;
- sb.compression |= pClientData->debugging ? fDebug : 0;
- sb.compression |= pClientData->loopback ? fLoopBack : 0;
- sb.compression |= compression ? fComp2X : 0;
- sb.compression |= gsmcompress ? fCompGSM : 0;
- sb.compression |= adpcmcompress ? fCompADPCM : 0;
- sb.compression |= lpccompress ? fCompLPC : 0;
- sb.compression |= (faceFile != HFILE_ERROR) ? fFaceOffer : 0;
-
- sendpkt(hwnd, pClientData, &sb);
- }
-
- /* CREATESOUNDBUFFER -- Create a standard format sound buffer
- with selected compression modes from a
- set of raw samples received from the audio
- input port. */
-
- void createSoundBuffer(LPSTR buffer, WORD buflen, DWORD channels,
- DWORD rate, DWORD bytesec, WORD align)
- {
- int knownFormat = FALSE;
-
- if (rate == 8000) {
- if (align == 2) {
- LONG i;
- int j;
-
- for (i = j = 0; i < (LONG) buflen / align; i++) {
- sb.buffer.buffer_val[j++] = audio_s2u((((WORD FAR *) buffer)[i]));
- }
- } else { // align == 1
- LONG i;
- int j;
-
- for (i = j = 0; i < (LONG) buflen; i++) {
- sb.buffer.buffer_val[j++] = audio_c2u((((BYTE FAR *) buffer)[i]));
- }
- }
- sb.buffer.buffer_len = buflen / align;
- knownFormat = TRUE;
- } else if (rate == 11025 && align == 2) {
- LONG i;
- int j, k;
-
- for (i = j = k = 0; i < (LONG) (buflen / align); i++) {
- if ((k & 3) != 2 && ((i % 580) != 579)) {
- sb.buffer.buffer_val[j++] = audio_s2u((((WORD FAR *) buffer)[i]));
- }
- k = (k + 1) % 11;
- }
- sb.buffer.buffer_len = j;
- knownFormat = TRUE;
- } else if (rate == 11025 && align == 1) {
- LONG i;
- int j, k;
-
- for (i = j = k = 0; i < (LONG) (buflen / align); i++) {
- if ((k & 3) != 2 && ((i % 580) != 579)) {
- sb.buffer.buffer_val[j++] = audio_c2u((((BYTE FAR *) buffer)[i]));
- }
- k = (k + 1) % 11;
- }
- sb.buffer.buffer_len = j;
- knownFormat = TRUE;
- }
-
- if (knownFormat) {
- if (compression) {
- compress2X(&sb);
- }
-
- if (gsmcompress) {
- gsmcomp(&sb);
- }
-
- if (adpcmcompress) {
- adpcmcomp(&sb);
- }
-
- if (lpccompress) {
- lpccomp(&sb);
- }
- }
- }
-
- /* CREATENEWCONNECTION -- Create a new connection MDI window. */
-
- HWND createNewConnection(LPCLIENT_DATA pClientData)
- {
- MDICREATESTRUCT mcs;
- HWND hwnd;
- SOCKERR serr = 0;
-
- #ifdef TRACE_FACE
- OutputDebugString("createNewConnection()\r\n");
- #endif
- mcs.szClass = pszClientClass;
- mcs.szTitle = pClientData->szHost,
- mcs.hOwner = hInst;
- mcs.x = CW_USEDEFAULT;
- mcs.y = CW_USEDEFAULT;
- mcs.cx = tmAveCharWidth * 30;
- mcs.cy = tmHeight * 5;
- mcs.style = 0;
-
- hwnd = FORWARD_WM_MDICREATE(hwndMDIClient, (LPMDICREATESTRUCT) &mcs, SendMessage);
-
- if (hwnd == NULL) {
- return NULL;
- }
-
- pClientData->state = Idle;
- SetWindowLong(hwnd, GWL_CLIENT, (LONG) pClientData);
- if (!pClientData->modemConnection) {
- serr = CreateSocket(&(pClientData->sReply), SOCK_DGRAM,
- htonl(INADDR_ANY), 0);
-
- if (serr == 0) {
- pClientData->name.sin_family = PF_INET;
- pClientData->name.sin_addr = pClientData->inetSock.sin_addr;
- pClientData->name.sin_port = htons(NETFONE_COMMAND_PORT);
-
- if (!waNetNoConnect) {
- if (connect(pClientData->sReply, (LPSOCKADDR) &(pClientData->name),
- sizeof(pClientData->name)) != 0) {
- serr = WSAGetLastError();
- }
- }
- #ifdef ASYNC_OUTPUT
- if (serr == 0) {
- serr = WSAAsyncSelect(pClientData->sReply, hwnd, WM_SOCKET_SELECT,
- FD_WRITE);
- }
- #endif
- }
- if (serr != 0) {
- MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(23),
- (LPSTR) pClientData->szHost, serr, SockerrToString(serr));
- return NULL;
- }
- }
-
- pClientData->gsmh = gsm_create();
-
- /* Since the sending buffer is static, there's no reason
- to get the host name for every packet (like, it doesn't
- change, right?). So just get it when we initialise a new
- connection. The nonsense with "gh" is because some WINSOCK
- implementations fail if the host buffer is too small, as
- opposed to truncating the name as Unix does. */
-
- {
- char gh[MAX_HOST];
-
- gethostname(gh, sizeof gh);
- if (strlen(gh) > ((sizeof sb.sendinghost) - 1)) {
- gh[(sizeof sb.sendinghost) - 1] = 0;
- }
- strcpy(sb.sendinghost, gh);
- }
-
- if (pClientData->modemConnection) {
- SetWindowText(hwnd, rstring(IDS_T_MODEM_CONNECTION));
- modemSessions++;
- } else if (pClientData->szHost[0] == '(') {
- /* This is a temporary connection initiated from the remote site.
- Schedule a lookup to obtain the full domain name of the host,
- not just the hostname included in the sound packet. */
- pClientData->getNameTask = WSAAsyncGetHostByAddr(hwnd, WM_SOCKET_ASYNC,
- (CHAR FAR *) &pClientData->inetSock.sin_addr,
- sizeof(pClientData->inetSock.sin_addr),
- PF_INET, pClientData->hostBuffer,
- sizeof(pClientData->hostBuffer));
- if (pClientData->getNameTask == NULL) {
- int serr = WSAGetLastError();
- MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(24),
- (LPSTR) pClientData->szHost, serr, SockerrToString(serr));
- }
- }
-
- DragAcceptFiles(hwnd, TRUE);
- ShowWindow(hwnd, SW_SHOW);
- openConnections++;
- propUpdateAudio();
-
- return hwnd;
- }
-
- // CONNFETCHFACE -- Begin retrieval of a face image.
-
- void connFetchFace(HWND hwndClient, LPCLIENT_DATA pClientData)
- {
- // pClientData->face_stat = FSabandoned;
- // if (pClientData->face_stat != -1) {
- #ifdef TRACE_FACE
- OutputDebugString("connFetchFace()\r\n");
- #endif
- pClientData->face_address = 0L;
- pClientData->face_timeout = 0;
- pClientData->face_retry = 0;
- pClientData->face_stat = FSreply; // Activate request from timeout
- SetTimer(hwndClient, 5, (UINT) FaceFetchInterval, NULL);
- // }
- }
-
- // STARTSOUNDFILE -- Begin playing a sound file.
-
- VOID startSoundFile(HWND hwnd, LPSTR pszFile)
- {
- LPCLIENT_DATA pClientData;
- HFILE hFile = HFILE_ERROR;
- char magic[4];
-
- pClientData = CLIENTPTR(hwnd);
-
- pClientData->quitSoundFile = FALSE;
- pClientData->hFile = HFILE_ERROR;
- if (pClientData->timeout > 0) {
- pClientData->timeout = 0;
- }
- pClientData->cbSent = 0L;
-
- // Try to open it
-
- hFile = _lopen(pszFile, OF_READ | OF_SHARE_DENY_WRITE);
-
- if (hFile == HFILE_ERROR) {
- // Error opening file
-
- MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(25),
- pszFile, (LPSTR) pClientData->szHost);
- goto FatalError;
- }
- _lread(hFile, magic, sizeof(long));
-
- /* See if it's a chunky, wavy RIFF. If so, delegate
- handling of the file to the multimedia I/O package. */
-
- if (memcmp(magic, "RIFF", 4) == 0) {
- _lclose(hFile);
- if (!readWaveInit(hwnd, pClientData, pszFile)) {
- return;
- }
- } else {
-
- /* If the file has a Sun .au file header, skip it.
- Note that we still blithely assume the file is
- 8-bit ISDN u-law encoded at 8000 samples per
- second. */
-
- if (memcmp(magic, ".snd", 4) == 0) {
- long startpos;
-
- _lread(hFile, &startpos, sizeof(long));
- revlong(&startpos);
- _llseek(hFile, startpos, 0);
- } else {
- _llseek(hFile, 0L, 0);
- }
- pClientData->hFile = hFile;
- }
-
- pClientData->state = Transferring;
- if (pClientData->timeout > 0) {
- pClientData->timeout = 0;
- }
-
- #ifdef SHOW_STATE
- InvalidateRect(hwnd, NULL, TRUE);
- UpdateWindow(hwnd);
- #endif
- DragAcceptFiles(hwnd, FALSE);
- if (SetTimer(hwnd, 2, 200, NULL) == 0) {
- MsgBox(NULL, MB_ICONSTOP | MB_OK, Format(26));
- }
- return;
-
- FatalError:
- if (hFile != HFILE_ERROR) {
- _lclose(hFile);
- }
- }
-
- /* FILEDROPPED -- Handle file dropped in connection window. */
-
- static VOID fileDropped(HWND hwnd, HDROP hdrop)
- {
- LPCLIENT_DATA pClientData;
-
- pClientData = CLIENTPTR(hwnd);
-
- // Retrieve the dropped file
-
- DragQueryFile(hdrop, 0, pClientData->szFile, sizeof(pClientData->szFile));
- DragFinish(hdrop);
-
- // Start output
-
- startSoundFile(hwnd, pClientData->szFile);
- }
-
- /* STATETOSTRING -- Convert state value to string. */
-
- static LPSTR stateToString(CLIENT_STATE state)
- {
- LPSTR pszResult;
-
- switch (state) {
- case Embryonic:
- pszResult = rstring(IDS_T_INITIALISING);
- break;
-
- case Idle:
- pszResult = rstring(IDS_T_IDLE);
- break;
-
- case SendingLiveAudio:
- pszResult = rstring(IDS_T_SENDING_LIVE);
- break;
-
- case Transferring:
- pszResult = rstring(IDS_T_SENDING_FILE);
- break;
-
- case PlayingReceivedAudio:
- pszResult = rstring(IDS_T_PLAYING_AUDIO);
- break;
-
- default:
- pszResult = rstring(IDS_T_UNKNOWN);
- break;
- }
- return pszResult;
- }
-
- /* CHANGEAUDIOSTATE -- Change transmitting / receiving state. */
-
- static void changeAudioState(HWND hwnd, LPCLIENT_DATA pClientData)
- {
- if (pClientData->face_shown) {
- LPSTR hname = pClientData->modemConnection ?
- rstring(IDS_T_MODEM_CONNECTION) : pClientData->szHost;
- if (pClientData->wantsInput) {
- char s[MAX_HOST + 20];
-
- strcpy(s, "==> ");
- _fstrcat(s, hname);
- SetWindowText(hwnd, s);
- } else {
- SetWindowText(hwnd, hname);
- }
- } else {
- InvalidateRect(hwnd, NULL, TRUE);
- UpdateWindow(hwnd);
- }
- }
-
- /* DESTROYCONNECTION -- Destroy connection, cleaning up debris
- and releasing resources. */
-
- static VOID destroyConnection(HWND hwnd, LPCLIENT_DATA pClientData)
- {
- if (pClientData->sReply != INVALID_SOCKET) {
- ResetSocket(pClientData->sReply);
- pClientData->sReply = INVALID_SOCKET;
- }
-
- if (pClientData->hFile != HFILE_ERROR) {
- _lclose(pClientData->hFile);
- pClientData->hFile = HFILE_ERROR;
- }
-
- pClientData->state = Idle;
-
- if (hwnd != NULL) {
- #ifdef SHOW_STATE
- InvalidateRect(hwnd, NULL, TRUE);
- UpdateWindow(hwnd);
- #endif
- DragAcceptFiles(hwnd, TRUE);
- }
- }
-
- /* CONNECT_WNDPROC -- Connection main window procedure. */
-
- LRESULT CALLBACK connectWndProc(HWND hwnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
- {
- LPCLIENT_DATA pClientData;
-
- pClientData = CLIENTPTR(hwnd);
-
- switch (nMessage) {
-
- // case WM_MDIACTIVATE:
- // if (wParam) {
- // InvalidateRect(hwnd, NULL, FALSE);
- // UpdateWindow(hwnd);
- // }
- // break;
-
- case WM_CHAR:
- if (wParam == ' ') {
- if (pClientData != NULL) {
- if (!pClientData->wantsInput) {
- goto spacebarOn;
- } else {
- goto spacebarOff;
- }
- }
- }
- return 0;
-
- case WM_CLOSE:
- if (pClientData != NULL) {
- destroyConnection(NULL, pClientData);
- }
- FORWARD_WM_CLOSE(hwnd, DefMDIChildProc);
- return 0;
-
- case WM_CREATE:
- #ifdef TRACE_FACE
- OutputDebugString("Connection WM_CREATE()\r\n");
- #endif
- SetFocus(hwnd);
- break;
-
- case WM_DESTROY:
- if (pClientData != NULL) {
- if (pClientData->wantsInput && --listeners <= 0) {
- terminateWaveInput();
- listeners = 0;
- }
- gsm_destroy(pClientData->gsmh);
- if (pClientData->hFile != HFILE_ERROR ||
- pClientData->mmioHandle != NULL) {
- KillTimer(hwnd, 2);
- if (pClientData->hFile != HFILE_ERROR) {
- _lclose(pClientData->hFile);
- }
- readWaveTerm(pClientData);
- }
-
- if (pClientData->pgpFileName[0] != 0) {
- KillTimer(hwnd, 3); // Kill timer for incomplete PGP poll
- // T'would be nice to clean up the temp files here as well.
- }
-
- if (pClientData->opgpFileName[0] != 0) {
- KillTimer(hwnd, 4); // Kill timer for incomplete PGP poll
- // T'would be nice to clean up the temp files here as well.
- }
-
- if (pClientData->face_stat == FSrequest ||
- pClientData->face_stat == FSreply) {
- KillTimer(hwnd, 5); // Kill timer for incomplete face image
- }
- if (pClientData->face_bmp != NULL) {
- GlobalFreePtr(pClientData->face_bmp); // Release face bitmap
- }
-
- if (pClientData->modemConnection) {
- modemSessions--;
- }
-
- if (pClientData->getNameTask != NULL) {
- WSACancelAsyncRequest(pClientData->getNameTask);
- pClientData->getNameTask = NULL;
- }
-
- GlobalFreePtr(pClientData);
- SetWindowLong(hwnd, GWL_CLIENT, 0L);
- }
- openConnections--;
- propUpdateAudio();
- return 0;
-
- case WM_DROPFILES:
- if (pClientData != NULL && !broadcasting) {
- pClientData->timeout = -1; // Send file immortalises connection
- fileDropped(hwnd, (HDROP) wParam);
- }
- break;
-
- #ifdef GATES_OF_HELL
-
- /* Well, golly, I though it would be kinda nice to keep
- the user from inflating the connection window larger than
- the face image in it--doing so only wastes screen
- real estate, after all. Little did I know that by trying
- to do so (at least with an MDI window), I stuck my toe
- back into the tree chipper and caused all kinds of
- things to let go--window size changing when iconised
- and reactivated, the "disappearing minimise button
- syndrome", etc. etc. The Developer CD serves up the
- usual crop of incoherent blithering. I give up--go
- ahead and make the bloody window as big as Siberia
- if you like. */
-
- case WM_GETMINMAXINFO:
- if (pClientData != NULL && pClientData->face_shown) {
- MINMAXINFO FAR *mm = (MINMAXINFO FAR *) lParam;
- BITMAPINFOHEADER FAR *bmi;
- RECT cr, wr;
-
- GetWindowRect(hwnd, &wr);
- GetClientRect(hwnd, &cr);
-
- bmi = (BITMAPINFOHEADER FAR *) (pClientData->face_bmp + sizeof(BITMAPFILEHEADER));
-
- // Don't allow resize of window larger than face
-
- mm->ptMaxSize.x = mm->ptMaxTrackSize.x = ((int) bmi->biWidth) + ((wr.right - wr.left) - cr.right);
- mm->ptMaxSize.x = mm->ptMaxTrackSize.y = ((int) bmi->biHeight) + ((wr.bottom - wr.top) - cr.bottom);
- }
- break;
- #endif
-
- case WM_LBUTTONDBLCLK:
- case WM_LBUTTONDOWN:
- spacebarOn: if (pClientData != NULL && !pClientData->wantsInput && !broadcasting) {
- if (listeners == 0) {
- if (!startWaveInput(hwnd)) {
- // Couldn't turn on wave audio input
- break;
- }
- }
- pClientData->wantsInput = (nMessage == WM_LBUTTONDBLCLK) ? 2 : TRUE;
- listeners++;
- pClientData->timeout = -1; // Send audio immortalises connection
- pClientData->state = SendingLiveAudio;
- SetCursor(earCursor);
- changeAudioState(hwnd, pClientData);
- }
- break;
-
- case WM_LBUTTONUP:
- spacebarOff:if (pClientData != NULL && !broadcasting) {
- if (pClientData->wantsInput == TRUE) {
- pClientData->wantsInput = FALSE;
- pClientData->state = pClientData->hFile != HFILE_ERROR ?
- Transferring : Idle;
- SetCursor(phoneCursor);
- changeAudioState(hwnd, pClientData);
- if (--listeners <= 0) {
- terminateWaveInput();
- listeners = 0;
- }
- /* If this the button-up following a double click, don't
- turn off listening. This allows a double click to latch
- input mode for a window. */
- } else if (pClientData->wantsInput == 2) {
- pClientData->wantsInput = TRUE;
- SetCursor(earCursor);
- UpdateWindow(hwnd);
- }
- }
- break;
-
- case WM_MOUSEMOVE:
- if (pClientData != NULL) {
- SetCursor((pClientData->wantsInput || broadcasting) ? earCursor :
- phoneCursor);
- }
- break;
-
- case WM_PAINT:
- {
- #define DCOL 11
- PAINTSTRUCT psPaint;
- HDC hdc;
- HBITMAP ibmap = NULL;
- int active = hwnd == ((HWND) LOWORD(SendMessage(hwndMDIClient, WM_MDIGETACTIVE, 0, 0L)));
-
- hdc = BeginPaint(hwnd, &psPaint);
- if (pClientData != NULL) {
- if (pClientData->face_stat == FScomplete &&
- pClientData->face_bmp != NULL) {
- int bx, by;
- RECT cr, wr;
- BITMAPFILEHEADER FAR *bfh;
- BITMAPINFOHEADER FAR *bmi;
- char _huge *bits;
- HPALETTE bpal = NULL, opal;
- int i;
- LPLOGPALETTE lp;
- BITMAPINFO FAR *bh;
- unsigned short FAR *palidx;
- LPSTR lpalette;
- unsigned short FAR *savepal;
- #ifdef TRACE_FACE
- { char s[256];
-
- wsprintf(s, "Paint %04X: %s\r\n", hwnd, pClientData->szHost);
- OutputDebugString(s);
- }
- #endif
-
- pClientData->face_shown = FALSE;
- savepal = (unsigned short FAR *) GlobalAllocPtr(GPTR,
- sizeof(LOGPALETTE) +
- sizeof(PALETTEENTRY) * 256 +
- sizeof(short) * 256);
- if (savepal == NULL) {
- goto face_failed;
- }
- lpalette = ((LPSTR) savepal) + 256 * sizeof(short);
- GetWindowRect(hwnd, &wr);
- GetClientRect(hwnd, &cr);
-
- bfh = (BITMAPFILEHEADER FAR *) pClientData->face_bmp;
- bmi = (BITMAPINFOHEADER FAR *) (pClientData->face_bmp + sizeof(BITMAPFILEHEADER));
- bh = (BITMAPINFO FAR *) bmi;
- bx = (int) bmi->biWidth;
- by = (int) bmi->biHeight;
-
- if (bmi->biClrUsed == 0) {
- bmi->biClrUsed = 1L << bmi->biBitCount;
- }
-
- bits = (char FAR *) (pClientData->face_bmp + bfh->bfOffBits);
-
- lp = (LOGPALETTE FAR *) lpalette;
- palidx = (unsigned short FAR *) bh->bmiColors;
- _fmemcpy(savepal, palidx, 256 * sizeof(short));
- lp->palVersion = 0x0300;
- lp->palNumEntries = (WORD) bmi->biClrUsed;
- for (i = 0; i < ((int) bmi->biClrUsed); i++) {
- lp->palPalEntry[i].peRed = bh->bmiColors[i].rgbRed;
- lp->palPalEntry[i].peGreen = bh->bmiColors[i].rgbGreen;
- lp->palPalEntry[i].peBlue = bh->bmiColors[i].rgbBlue;
- lp->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
- if (active) {
- // palidx[i] = (unsigned short) i;
- }
- }
- bpal = CreatePalette(lp);
- if (active && bpal != NULL) {
- opal = SelectPalette(hdc, bpal, FALSE);
- RealizePalette(hdc);
- }
-
- ibmap = CreateDIBitmap(hdc, bmi, CBM_INIT,
- bits, (BITMAPINFO FAR *) bmi, DIB_RGB_COLORS);
- _fmemcpy(palidx, savepal, 256 * sizeof(short));
- if (ibmap != NULL) {
- HDC hMemDC;
- HBITMAP obmap;
- HPALETTE mopal;
-
- hMemDC = CreateCompatibleDC(hdc);
- if (bpal != NULL) {
- mopal = SelectPalette(hMemDC, bpal, FALSE);
- }
- obmap = SelectObject(hMemDC, ibmap);
- if (bx <= cr.right && by <= cr.bottom) {
- BitBlt(hdc, (cr.right - bx) / 2, (cr.bottom - by) / 2,
- bx, by, hMemDC, 0, 0, SRCCOPY);
- } else {
- int nx, ny;
- double xshrink = ((double) bx) / cr.right,
- yshrink = ((double) by) / cr.bottom;
-
- #ifdef TRACE_FACE
- OutputDebugString("Yick!!! Had to stretch face bitmap.\r\n");
- #endif
- if (xshrink > yshrink) {
- nx = cr.right;
- ny = (int) (by / xshrink);
- } else {
- ny = cr.bottom;
- nx = (int) (bx / yshrink);
- }
- SetStretchBltMode(hdc, STRETCH_DELETESCANS);
- StretchBlt(hdc, (cr.right - nx) / 2, (cr.bottom - ny) / 2, nx, ny,
- hMemDC, 0, 0, bx, by, SRCCOPY);
- }
- SelectObject(hMemDC, obmap);
- DeleteObject(ibmap);
- if (bpal != NULL) {
- if (active) {
- SelectPalette(hdc, opal, FALSE);
- }
- SelectPalette(hMemDC, mopal, FALSE);
- DeleteObject(bpal);
- }
- DeleteDC(hMemDC);
- pClientData->face_shown = TRUE;
- }
- GlobalFreePtr(savepal);
- }
- face_failed:
- if (!pClientData->face_shown) {
- WinPrintf(hdc, 0, 1, pClientData->modemConnection ?
- rstring(IDS_T_DIAL_STRING) : rstring(IDS_T_HOST));
- WinPrintf(hdc, 0, DCOL, pClientData->szHost);
-
- if (pClientData->modemConnection) {
- WinPrintf(hdc, 1, 1, rstring(IDS_T_MODEM_CONNECTION_L));
- } else {
- WinPrintf(hdc, 1, 1, rstring(IDS_T_ADDRESS));
- WinPrintf(hdc, 1, DCOL, Format(48), inet_ntoa(pClientData->inetSock.sin_addr));
- }
-
- WinPrintf(hdc, 2, 1, pClientData->wantsInput ? rstring(IDS_T_TRANSMITTING) :
- rstring(IDS_T_BLANKTRANSMIT));
-
- #ifdef SHOW_STATE
- /* It's nice to show the state, but costly to update on
- every packet. */
-
- WinPrintf(hdc, 3, 1, "State:");
- WinPrintf(hdc, 3, DCOL, "%s", stateToString(pClientData->state));
-
- switch (pClientData->state) {
- case Idle:
- WinPrintf(hdc, 4, 1, blankit);
- WinPrintf(hdc, 5, 1, blankit);
- break;
-
- case Transferring:
- WinPrintf(hdc, 4, 1, "File: ");
- WinPrintf(hdc, 4, DCOL, "%s", pClientData->szFile);
- WinPrintf(hdc, 5, 1, "Bytes sent:");
- WinPrintf(hdc, 5, DCOL, "%lu", pClientData->cbSent);
- break;
-
- case PlayingReceivedAudio:
- WinPrintf(hdc, 4, 1, "Bytes received:");
- WinPrintf(hdc, 4, DCOL, "%lu", pClientData->cbReceived);
- break;
- }
- #endif
- }
- #undef DCOL
- }
-
- EndPaint(hwnd, &psPaint);
- }
- break;
-
- case WM_MDIACTIVATE:
- if (wParam == FALSE || IsIconic(hwnd)) {
- break;
- }
- if (pClientData != NULL && pClientData->face_shown) {
- HDC hdc;
- BITMAPINFOHEADER FAR *bmi;
- HPALETTE bpal = NULL, opal;
- int i;
- LPLOGPALETTE lp;
- BITMAPINFO FAR *bh;
- LPSTR lpalette;
- #ifdef TRACE_FACE
- { char s[256];
-
- wsprintf(s, "MDI activate %04X: %s\r\n", hwnd, pClientData->szHost);
- OutputDebugString(s);
- }
- #endif
-
- lpalette = GlobalAllocPtr(GPTR, sizeof(LOGPALETTE) +
- sizeof(PALETTEENTRY) * 256);
- if (lpalette != NULL) {
- bmi = (BITMAPINFOHEADER FAR *) (pClientData->face_bmp + sizeof(BITMAPFILEHEADER));
- bh = (BITMAPINFO FAR *) bmi;
- lp = (LOGPALETTE FAR *) lpalette;
- lp->palVersion = 0x0300;
- lp->palNumEntries = (WORD) bmi->biClrUsed;
- for (i = 0; i < ((int) bmi->biClrUsed); i++) {
- lp->palPalEntry[i].peRed = bh->bmiColors[i].rgbRed;
- lp->palPalEntry[i].peGreen = bh->bmiColors[i].rgbGreen;
- lp->palPalEntry[i].peBlue = bh->bmiColors[i].rgbBlue;
- lp->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
- }
- bpal = CreatePalette(lp);
- if (bpal != NULL) {
- hdc = GetDC(hwnd);
- opal = SelectPalette(hdc, bpal, FALSE);
- i = RealizePalette(hdc);
- SelectPalette(hdc, opal, FALSE);
- DeleteObject(bpal);
- ReleaseDC(hwnd, hdc);
- if (i > 0) {
- HWND oldwin;
-
- InvalidateRect(hwnd, NULL, TRUE);
- UpdateWindow(hwnd);
- oldwin = (HWND) HIWORD(lParam);
- if (oldwin != NULL) {
- InvalidateRect(oldwin, NULL, TRUE);
- UpdateWindow(oldwin);
- }
- }
- return i;
- }
- GlobalFreePtr(lpalette);
- }
- }
- break;
-
- #ifdef ASYNC_OUTPUT
- case WM_SOCKET_SELECT:
- if (pClientData != NULL) {
- pClientData->outputSocketBusy = FALSE;
- }
- return 0;
- #endif
-
- case WM_SOCKET_ASYNC:
- if (pClientData != NULL) {
- if (WSAGETASYNCERROR(lParam) == 0) {
- LPHOSTENT host;
-
- pClientData->getNameTask = NULL;
- host = (LPHOSTENT) pClientData->hostBuffer;
- SetWindowText(hwnd, host->h_name);
- _fstrcpy(pClientData->szHost, host->h_name);
- changeAudioState(hwnd, pClientData);
- } else {
- MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(27),
- pClientData->szHost, WSAGETASYNCERROR(lParam),
- SockerrToString(WSAGETASYNCERROR(lParam)));
- }
- }
- break;
-
- case WM_TIMER:
- {
- DWORD startTicks = GetTickCount();
-
- if (pClientData == NULL) {
- break;
- }
-
- /* If there are no buffers pending, advance the timeout
- counter. When it reaches TIMEOUT_CONNECTION, close the
- connection. */
-
- if (wParam == FRAME_TIMER_ID && !broadcasting &&
- pClientData->timeout >= 0 && outputPending == 0) {
- if ((pClientData->timeout++) >= TIMEOUT_CONNECTION) {
- FORWARD_WM_MDIDESTROY(hwndMDIClient, hwnd, SendMessage);
- return 0;
- }
- if (pClientData->timeout == 5) {
- if (!IsIconic(hwnd)) {
- pClientData->cbReceived = 0;
- pClientData->state = Idle;
- if (pClientData->face_stat == -1) {
- pClientData->face_stat = FSinit;
- }
- #ifdef SHOW_STATE
- InvalidateRect(hwnd, NULL, TRUE);
- UpdateWindow(hwnd);
- #endif
- }
- }
- }
-
- /* If a broadcast is underway and the site has requested
- to unsubscribe, close the connection after a decent
- interval has elapsed to avoid toggling due to multiple
- packets. */
-
- if (wParam == FRAME_TIMER_ID && broadcasting &&
- pClientData->broadcastEnd &&
- ((GetTickCount() - pClientData->broadcastBeginTime) >
- (BroadcastUnsubscribe * 1000L))) {
- FORWARD_WM_MDIDESTROY(hwndMDIClient, hwnd, SendMessage);
- return 0;
- }
-
- /* Cadence timer indicating it's time to send the
- next block of a sound file. Read it in and send
- it on its way. */
-
- if (wParam == 2 && pClientData->hFile != HFILE_ERROR ||
- pClientData->mmioHandle != NULL) {
- long et;
- UINT bread = 0;
-
- if (pClientData->modemConnection) {
- int err;
- COMSTAT cs;
-
- err = GetCommError(modemHandle, &cs);
- if (cs.cbOutQue > 1000) {
- /* If modem connection and modem's backed up
- with output, spin until it goes idle. */
- SetTimer(hwnd, 2, 10, NULL);
- break;
- }
- }
- if (pClientData->mmioHandle != NULL) {
- // Queue next packet from .WAV input file
- if (!pClientData->quitSoundFile) {
- bread = readWaveNext(hwnd, pClientData);
- }
- if (bread == 0) {
- readWaveTerm(pClientData);
- } else {
- bread = (UINT) ((bread * 8000L) / 11025L);
- }
- } else {
- // Queue next packet from .AU input file
- if (!pClientData->quitSoundFile) {
- bread = _lread(pClientData->hFile,
- sb.buffer.buffer_val, currentInputSamples);
- }
- if (bread == 0) {
- _lclose(pClientData->hFile);
- pClientData->hFile = HFILE_ERROR;
- } else {
- sb.buffer.buffer_len = bread;
- /* Since we're manufacturing our own sound buffer
- in place rather than calling CreateSoundBuffer(),
- we need to apply whatever compression is requested
- here before shipping the buffer. */
- if (compression) {
- compress2X(&sb);
- }
- if (gsmcompress) {
- gsmcomp(&sb);
- }
- if (adpcmcompress) {
- adpcmcomp(&sb);
- }
- if (lpccompress) {
- lpccomp(&sb);
- }
- shipSoundBuffer(hwnd, pClientData);
- }
- }
-
- if (bread == 0) {
- KillTimer(hwnd, 2);
- pClientData->state = pClientData->wantsInput ? SendingLiveAudio : Idle;
- DragAcceptFiles(hwnd, TRUE);
- #ifdef SHOW_STATE
- InvalidateRect(hwnd, NULL, TRUE);
- UpdateWindow(hwnd);
- #endif
- return 0;
- }
- pClientData->cbSent += bread;
- #ifdef SHOW_STATE
- InvalidateRect(hwnd, NULL, TRUE);
- UpdateWindow(hwnd);
- #endif
-
- // If window isn't immortal, reset the timeout
- if (pClientData->timeout > 0) {
- pClientData->timeout = 0;
- }
-
- /* The following code is needed because when we're reading
- sound from a file, as opposed to receiving it in real
- time from the CODEC, we must meter out the samples
- at the rate they will actually be played by the destination
- machine. For 8000 samples per second, this amounts
- to 125 microseconds per sample, minus the time we spent
- compressing the data (which is substantial for GSM) and
- a fudge factor, kOverhead, which accounts for the time
- spent in executing the delay itself and getting control
- back after it's done. If sound files pause periodically
- (when the sending machine isn't loaded), you may need
- to reduce the delay parameters. If they're too low,
- however, data will be lost when sending long sound files. */
-
- #define kOverhead 25000
- et = ((bread * 125L) - kOverhead) -
- ((GetTickCount() - startTicks) * 1000);
- if (et <= 0) {
- et = 10;
- }
- SetTimer(hwnd, 2, (UINT) (et / 1000), NULL);
- #ifdef DBT
- if (!IsIconic(hwnd)) {
- HDC hdc = GetDC(hwnd);
-
- WinPrintf(hdc, 6, 1, "Timer reset to %d ms.", (UINT) (et / 1000));
- ReleaseDC(hwnd, hdc);
- }
- #endif
- }
-
- /* Timer indicating a periodic PGP poll is underway.
- If PGP has finished writing the decoded session key
- file, read it into the connection structure and put
- it into effect, then sweep up after PGP. */
-
- if (wParam == 3) {
- HFILE kfile = _lopen(pClientData->pgpFileName,
- READ_WRITE | OF_SHARE_EXCLUSIVE);
-
- if (kfile == HFILE_ERROR) {
- // Still not done. Reset the timer
- SetTimer(hwnd, 3, 1000, NULL);
- } else {
- if (_lread(kfile, pClientData->pgpkey, 17) == 17) {
- char yfn[MAX_PATH];
- int i;
- unsigned char ow[16];
-
- pClientData->pgpkey[0] = TRUE;
-
- // Overwrite the session key on disc
-
- _llseek(kfile, 0L, 0);
- for (i = 0; i < 16; i++) {
- ow[i] = 0xFF;
- }
- _lwrite(kfile, ow, 16);
- _llseek(kfile, 0L, 0);
- for (i = 0; i < 16; i++) {
- ow[i] = 0;
- }
- _lwrite(kfile, ow, 16);
-
- _lclose(kfile);
- _fstrcpy(yfn, pClientData->pgpFileName);
- _unlink(yfn);
- _fstrcat(yfn, ".TMP");
- _unlink(yfn);
- pClientData->pgpFileName[0] = 0;
- KillTimer(hwnd, 3);
- } else {
- pClientData->pgpkey[0] = FALSE;
- SetTimer(hwnd, 3, 1000, NULL);
- _lclose(kfile);
- }
- }
- }
-
- /* Timer indicating a periodic PGP poll is underway.
- If PGP has finished writing the encoded session key
- file, read it into the connection structure and put
- it into effect, then sweep up after PGP. */
-
- if (wParam == 4) {
- HFILE kfile = _lopen(pClientData->opgpFileName,
- READ | OF_SHARE_EXCLUSIVE);
-
- if (kfile == HFILE_ERROR) {
- // Still not done. Reset the timer
- SetTimer(hwnd, 4, 1000, NULL);
- } else {
- int len;
-
- if ((len = _lread(kfile, ebuf.buffer.buffer_val, BUFL)) > 0) {
- int i;
- char yfn[MAX_PATH];
-
- ebuf.buffer.buffer_len = len;
- pClientData->opgpkey[0] = TRUE; // Activate outbound PGP key
- ebuf.compression = fKeyPGP;
- {
- char gh[MAX_HOST];
-
- gethostname(gh, sizeof gh);
- if (strlen(gh) > ((sizeof ebuf.sendinghost) - 1)) {
- gh[(sizeof ebuf.sendinghost) - 1] = 0;
- }
- strcpy(ebuf.sendinghost, gh);
- }
- revlong(&ebuf.compression);
- revlong(&ebuf.buffer.buffer_len);
-
- for (i = 0; i < 3; i++) {
- if (writeOutput(pClientData, (LPSTR) &ebuf,
- (int) ((sizeof(struct soundbuf) - BUFL) +
- len)) < 0) {
- break;
- }
- }
- _lclose(kfile);
-
- _fstrcpy(yfn, pClientData->opgpFileName);
- _unlink(yfn);
- yfn[_fstrlen(yfn) - 3] = 0;
- _fstrcat(yfn, "TMP");
-
- // Overwrite the session key on disc
-
- kfile = _lopen(yfn, READ_WRITE | OF_SHARE_EXCLUSIVE);
- if (kfile != HFILE_ERROR) {
- int i;
- unsigned char ow[16];
-
- for (i = 0; i < 16; i++) {
- ow[i] = 0xFF;
- }
- _lwrite(kfile, ow, 16);
- _llseek(kfile, 0L, 0);
- for (i = 0; i < 16; i++) {
- ow[i] = 0;
- }
- _lwrite(kfile, ow, 16);
- _lclose(kfile);
- }
- _unlink(yfn);
- pClientData->opgpFileName[0] = 0;
- KillTimer(hwnd, 4);
- } else {
- SetTimer(hwnd, 4, 1000, NULL);
- _lclose(kfile);
- }
- }
- }
-
- /* Cadence timer regulating retrieval of a face
- image from the connected host. */
-
- if (wParam == 5) {
- int makereq = FALSE;
-
- /* If a face file transfer is in progress, request
- the next block or, if it's time, re-issue the last
- request if the timeout has expired. */
-
- if (pClientData->face_stat == FSreply) {
- makereq = TRUE;
- pClientData->face_retry = 0;
- #ifdef TRACE_FACE
- { char s[MAX_HOST + 80];
-
- wsprintf(s, "Request face data at %ld from %s\r\n",
- pClientData->face_address, pClientData->szHost);
- OutputDebugString(s);
- }
- #endif
- } else if (pClientData->face_stat == FSrequest) {
- pClientData->face_timeout++;
- if (pClientData->face_timeout >= FaceTimeout) {
- #ifdef TRACE_FACE
- { char s[MAX_HOST + 80];
-
- wsprintf(s, "Retry %d reissue face data request at %ld from %s\r\n",
- pClientData->face_retry, pClientData->face_address,
- pClientData->szHost);
- OutputDebugString(s);
- }
- #endif
- if (pClientData->face_retry > FaceMaxRetries) {
- /*
- if (pClientData->face_file != NULL) {
- fclose(c->face_file);
- c->face_file = NULL;
- }
- unlink(c->face_filename);
- c->face_filename[0] = 0;
- */
- pClientData->face_stat = FSabandoned;
- if (pClientData->face_bmp != NULL) {
- GlobalFreePtr(pClientData->face_bmp);
- pClientData->face_bmp = NULL;
- }
- KillTimer(hwnd, 5);
- #ifdef TRACE_FACE
- { char s[MAX_HOST + 80];
-
- wsprintf(s, "Timeout, no face image available for %s\r\n",
- pClientData->szHost);
- OutputDebugString(s);
- }
- #endif
- } else {
- makereq = TRUE;
- pClientData->face_retry++;
- }
- }
- } else {
- KillTimer(hwnd, 5); // Terminated due to data format error
- #ifdef TRACE_FACE
- OutputDebugString("Face timer shut down.\r\n");
- #endif
- }
-
- if (makereq) {
- pClientData->face_stat = FSrequest;
- pClientData->face_timeout = 0;
- sb.compression = htonl(fFaceData | faceRequest);
- sb.buffer.buffer_len = htonl(pClientData->face_address);
- if (writeOutput(pClientData, (LPSTR) &sb, sizeof(soundbuf) - BUFL) < 0) {
- pClientData->face_stat = FSabandoned;
- // *** CLEAN UP DEBRIS
- }
- }
- }
- }
- return 0;
- }
- return DefMDIChildProc(hwnd, nMessage, wParam, lParam);
- }
-
-
-